package com.adou.multi.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.adou.multi.domain.entiry.Product;
import com.adou.multi.model.ProductValue;
import com.adou.multi.multi_tenancy.page.PageResult;
import com.adou.multi.respository.ProductRespository;
import com.adou.multi.service.ProductService;

@Service
public class ProductServiceImpl implements ProductService {
	@Autowired
	private ProductRespository productRespository;

	@Override
	public List<ProductValue> getProducts() {
		return StreamSupport.stream(productRespository.findAll().spliterator(), false).map(ProductValue::fromEntity)
				.collect(Collectors.toList());
	}

	@Override
	public ProductValue getProduct(long id) {
		return productRespository.findById(id).map(ProductValue::fromEntity)
				.orElseThrow(() -> new EntityNotFoundException("Proct " + id + " not found"));
	}

	@Override
	public ProductValue createProduct(ProductValue productValue) {
		Product product = Product.builder().name(productValue.getName()).build();
		product = productRespository.save(product);

		return ProductValue.fromEntity(product);
	}

	@Override
	public ProductValue updateProduct(ProductValue productValue) {
		Product product = productRespository.findById(productValue.getId())
				.orElseThrow(() -> new EntityNotFoundException("Proct " + productValue.getId() + " not found"));

		product.setName(productValue.getName());

		return ProductValue.fromEntity(product);
	}

	@Override
	public void deleteProductById(long id) {
		Product product = productRespository.findById(id)
				.orElseThrow(() -> new EntityNotFoundException("Proct " + id + " not found"));
		productRespository.delete(product);
	}

	public PageResult<ProductValue> qryProductValuePage(Integer pageNumber, Integer pageSize, String orderColumn,
			String orderClumnSortString, ProductValue dto) {
		orderColumn = orderColumn == null ? "id" : orderColumn;
		Sort.Direction orderColumnSort = orderClumnSortString == null ? Sort.Direction.DESC
				: Sort.Direction.valueOf(orderClumnSortString);
		Specification<Product> queryConditions = new Specification<Product>() {

			@Override
			public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
				List<Predicate> predicates = new ArrayList<>();
				 if(dto.getName() != null) {
					 predicates.add(criteriaBuilder.equal(root.get("name"), dto.getName()));
				 }
				Predicate predicateAnd = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
				return query.where(predicateAnd).getRestriction();
			}

		};

		Pageable page = PageRequest.of(pageNumber - 1, pageSize, orderColumnSort, orderColumn);
		Page<Product> products = productRespository.findAll(queryConditions, page);
		List<Product> productList = products.getContent();
		List<ProductValue> productValueList = new ArrayList<>();
		// 返回结果设置
		if (!CollectionUtils.isEmpty(productList)) {
			productList.forEach(t -> {
				ProductValue productValue = new ProductValue();
				BeanCopier.create(Product.class, ProductValue.class, false).copy(t, productValue, null);
				productValueList.add(productValue);
			});
		}
		PageResult<ProductValue> result = new PageResult<>(products.getNumber(), products.getSize(),
				(int) products.getTotalElements(), productValueList);
		return result;

	}

}
